
/**
  ******************************************************************************
  * Copyright 2021 The Microbee Authors. All Rights Reserved.
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  * 
  * http://www.apache.org/licenses/LICENSE-2.0
  * 
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  * 
  * @file       notify_pixracer_led.c
  * @author     baiyang
  * @date       2022-6-8
  ******************************************************************************
  */

/*----------------------------------include-----------------------------------*/
#include "notify_pixracer_led.h"

#include <rtthread.h>
#include <rtdevice.h>

#if (defined(HAL_HAVE_PIXRACER_LED) && defined(RT_USING_PIN))

/*-----------------------------------macro------------------------------------*/
#ifndef HAL_GPIO_A_LED_PIN
#define HAL_GPIO_A_LED_PIN        -1
#endif
#ifndef HAL_GPIO_B_LED_PIN
#define HAL_GPIO_B_LED_PIN        -1
#endif
#ifndef HAL_GPIO_C_LED_PIN
#define HAL_GPIO_C_LED_PIN        -1
#endif

#ifndef HAL_GPIO_LED_ON
#define HAL_GPIO_LED_ON           0
#endif
#ifndef HAL_GPIO_LED_OFF
#define HAL_GPIO_LED_OFF          1
#endif
/*----------------------------------typedef-----------------------------------*/

/*---------------------------------prototype----------------------------------*/
static void bind_function(pixracer_led_t pixracerled);
static bool init(notify_device_t notify_dev);
static bool hw_set_rgb(rgb_led_t led, uint8_t r, uint8_t g, uint8_t b);
/*----------------------------------variable----------------------------------*/
static struct rgb_led_ops pixracer_led_ops;
static struct notify_device_ops pixracer_notify_dev_ops;
/*-------------------------------------os-------------------------------------*/

/*----------------------------------function----------------------------------*/
void pixracer_led_ctor(pixracer_led_t pixracerled)
{
    rgb_led_ctor(&pixracerled->backend_rgb, 0, 1, 1, 1);

    bind_function(pixracerled);
}

notify_device_t pixracer_led_probe()
{
    pixracer_led_t pixracerled = (pixracer_led_t)rt_malloc(sizeof(struct pixracer_led));

    if (pixracerled) {
        rt_memset(pixracerled, 0, sizeof(struct pixracer_led));
        pixracer_led_ctor(pixracerled);

        return (notify_device_t)pixracerled;
    }

    return NULL;
}

static void bind_function(pixracer_led_t pixracerled)
{
    pixracer_led_ops = rgb_led_ops();
    pixracer_notify_dev_ops = rgb_led_notify_device_ops();

    pixracer_led_ops.hw_set_rgb = hw_set_rgb;
    pixracer_notify_dev_ops.init = init;

    pixracerled->backend_rgb.ops = &pixracer_led_ops;
    pixracerled->backend_rgb.notify_dev.ops = &pixracer_notify_dev_ops;
}

static bool init(notify_device_t notify_dev)
{
    // when HAL_GPIO_LED_ON is 0 then we must not use pinMode()
    // as it could remove the OPENDRAIN attribute on the pin
#if HAL_GPIO_LED_ON != 0
    rt_pin_mode(HAL_GPIO_A_LED_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(HAL_GPIO_B_LED_PIN, PIN_MODE_OUTPUT);
    rt_pin_mode(HAL_GPIO_C_LED_PIN, PIN_MODE_OUTPUT);
#else
    rt_pin_mode(HAL_GPIO_A_LED_PIN, PIN_MODE_OUTPUT_OD);
    rt_pin_mode(HAL_GPIO_B_LED_PIN, PIN_MODE_OUTPUT_OD);
    rt_pin_mode(HAL_GPIO_C_LED_PIN, PIN_MODE_OUTPUT_OD);
#endif
    rt_pin_write(HAL_GPIO_A_LED_PIN, HAL_GPIO_LED_OFF);
    rt_pin_write(HAL_GPIO_B_LED_PIN, HAL_GPIO_LED_OFF);
    rt_pin_write(HAL_GPIO_C_LED_PIN, HAL_GPIO_LED_OFF);
    return true;
}

static bool hw_set_rgb(rgb_led_t led, uint8_t r, uint8_t g, uint8_t b)
{
    rt_pin_write(HAL_GPIO_A_LED_PIN, (r > 0)?HAL_GPIO_LED_ON:HAL_GPIO_LED_OFF);
    rt_pin_write(HAL_GPIO_B_LED_PIN, (g > 0)?HAL_GPIO_LED_ON:HAL_GPIO_LED_OFF);
    rt_pin_write(HAL_GPIO_C_LED_PIN, (b > 0)?HAL_GPIO_LED_ON:HAL_GPIO_LED_OFF);
    return true;
}

#else
notify_device_t pixracer_led_probe() { return NULL;}
static bool init(notify_device_t notify_dev) { return true; }
static bool hw_set_rgb(uint8_t r, uint8_t g, uint8_t b) { return true; }

/*------------------------------------test------------------------------------*/
#endif


